有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java我想设置一个私有字段来测试函数

我有一个bean,它有一个函数getUser,它返回当前登录的用户,或者如果变量user为空,就会找到一个

我的bean中是否有糟糕的设计,还是应该创建一个setUser函数?我不确定正确的方法是什么

这是我对授权bean的测试:

public class AuthorizationBeanTest {

    private AuthorizationBean authorizationBean;

    @Mock
    User user;

    @Mock
    UserDao userDao;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        authorizationBean = new AuthorizationBean();
        //I want to set the user to the mocked user so I can test the logout function
    }

    @Test
    public void doLogoutTest() {
        assertNotNull(authorizationBean.getUser());
        assertEquals("/login.xhtml?faces-redirect=true", authorizationBean.doLogout());
        assertNull(authorizationBean.getUser());
    }

}

下面是bean中的代码:

@ManagedBean(name = "authBean")
@SessionScoped
public class AuthorizationBean implements Serializable{

    //Data access object for the users
    @Inject
    UserDao userDao;

    private User user; // The JPA entity.
    public User getUser() {
        if (user == null) {
            user = (User) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
            if (user == null) {
                Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
                if (principal != null) {
                    user = userDao.findByEmail(principal.getName()); // Find User by j_username.
                }
            }
        }
        return user;
    }

    /**
     * Function that handles the logout
     * @return Redirect string that points to the login page
     */
    public String doLogout() {
        // invalidate the session, so that the session is removed
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        user = null;
        // return redirect to login page
        return "/login.xhtml?faces-redirect=true";
    }


}

共 (3) 个答案

  1. # 1 楼答案

    您可以使用good(或bad,根据您的喜好)oldjava.reflection包来设置私有字段

    Field userField = authorizationBean.getClass().getDeclaredField("user");
    userField.setAccessible(true);
    userField.set(authorizationBean, someUser);
    

    在测试范围内,我认为它并不像看上去那么糟糕

  2. # 2 楼答案

    您可以在@Before方法中模拟用户,如下所示:

    Mockito.when(authorizationBean.getUser()).thenReturn(user);
    

    为此,您还需要模拟AuthorizationBean类

    也可以省略注释。(这个);调用使用Mockito runner运行整个测试,将此注释放置在测试类上:

    @RunWith(MockitoJUnitRunner.class)
    

    更新:但是,如果你真的模仿它,你将无法测试AuthorizationBean。bean中有几个静态方法调用,您可以使用PowerMock对它们进行模拟,但是使用PowerMock对审查设计来说也是一种不好的味道

    更新2: 使用PowerMock,您实际上可以执行以下操作:

    PowerMockito.mockStatic(FacesContext.class);
    PowerMockito.when(FacesContext.getCurrentInstance()).thenReturn(context);
    

    其中context是另一个mock,它将用您的mock用户填充会话映射

    更新3:不要忘记运行测试用例,然后使用@RunWith(PowerMockRunner.class)。你可以查看一个更详细的例子here,但是如果将来链接会断开,上面的说明应该已经给了你一个好的开始

  3. # 3 楼答案

    为了简单起见,我通常会将字段包设置为私有,并用guava's ^{}注释它

    @VisibleForTesting User user; // The JPA entity.